package heap

/*
三种情况下s类型引用值可以赋给T类型
*/
func (self *Class) isAssignableFrom(other *Class) bool {
	s, t := other, self
	if s == t {
		return true
	}
	// self 非 array
	if !s.IsArray() {
		// self 非 interface
		if !s.IsInterface() {
			// t 非接口
			if !t.IsInterface() {
				// s 为 t 子类即可为其赋值
				return s.IsSubClassOf(t)
			} else {
				// t 是接口，s 必须实现 t 才能进行赋值
				return s.IsImplements(t)
			}
		} else {
			// s 是接口
			if !t.IsInterface() {
				// t 非接口, s 要为 t 赋值 t只能为 Object类
				return t.isJlObject()
			} else {
				// t是接口， 那么 t 必须为父接口才可以被赋值
				return t.isSuperInterfaceOf(s)
			}
		}
	} else {
		// s 是数组类
		if !t.IsArray() {
			// t 不是接口
			if !t.IsInterface() {
				return t.isJlObject()
			} else {
				// t 是接口
				return t.isJlCloneable() || t.isJioSerializable()
			}
		} else {
			sc := s.ComponentClass()
			tc := t.ComponentClass()
			return sc == tc || tc.isAssignableFrom(sc)
		}
	}
	return false
}

func (self *Class) IsSubClassOf(other *Class) bool {
	// 逐级向上寻找，如若找到一个类与other相等，就返回true(类似迭代)
	for c := self.superClass; c != nil; c = c.superClass {
		if c == other {
			return true
		}
	}
	return false
}

func (self *Class) IsImplements(intfa *Class) bool {
	// 同样逐级向上寻找，由于接口是一个切片保存，所以需要内层再次遍历
	for c := self; c != nil; c = c.superClass {
		for _, i := range c.interfaces {
			// 在当前类中找到接口，判断是否在当前类实现了接口。或者存在目标接口的子接口。
			if i == intfa || i.isSubInterfaceOf(intfa) {
				return true
			}
		}
	}
	return false
}

// 子接口判断逻辑（递归实现）
// 进入到每个接口中，遍历每个接口继承的父的接口
func (self *Class) isSubInterfaceOf(intfa *Class) bool {
	for _, superInterface := range self.interfaces {
		if superInterface == intfa || superInterface.isSubInterfaceOf(intfa) {
			return true
		}
	}
	return false
}

func (self *Class) IsSuperClassOf(other *Class) bool {
	return other.IsSubClassOf(self)
}

func (self *Class) isSuperInterfaceOf(intf *Class) bool {
	return intf.isSubInterfaceOf(self)
}
